<template>
  <el-form label-width="100px">
    <el-form-item label="SPU名称">
      <el-input v-model="spuParams.spuName" placeholder="请输入SPU名称"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select v-model="spuParams.tmId" placeholder="请选择SPU品牌">
        <el-option v-for="(item,index) in allTradeMark" :key="index" :label="item.tmName" :value="item.id"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input v-model="spuParams.description" type="textarea" placeholder="请输入SPU描述"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片">
      <!-- 
        v-model:file-list 展示默认图片列表
        action 上传图片接口地址
        list-type 文件列表类型 'text'文件名 | 'picture'图片 | 'picture-card'照片墙
        on-preview 文件预览
        on-remove 文件删除
       -->
      <el-upload
        v-model:file-list="imgList"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :before-upload="handleUpload"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%;height: 100%;"/>
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <el-select v-model="saleAttrIdAndValueName" :placeholder="unSelectSaleAttr.length?`还未选择${unSelectSaleAttr.length}个`:'无'">
        <el-option :value="`${item.id}:${item.name}`" v-for="(item,index) in unSelectSaleAttr" :key="index" :label="item.name"></el-option>
      </el-select>
      <el-button @click="addSaleAttr" type="primary" icon="Plus" style="margin-left: 10px;" :disabled="saleAttrIdAndValueName?false:true">添加属性</el-button>
      <el-table :data="saleAttr" border style="margin: 10px 0;">
        <el-table-column label="序号" type="index" align="center" width="120px"></el-table-column>
        <el-table-column prop="saleAttrName" label="销售属性名字" align="center" width="120px"></el-table-column>
        <el-table-column label="销售属性值" align="center">
          <template #="{row}">
            <el-tag v-for="(item,index) in row.spuSaleAttrValueList" :key="index" type="success" closable 
            @close="row.spuSaleAttrValueList.splice(index,1)" class="mx-1" style="margin: 0 5px;">
              {{ item.saleAttrValueName }}
            </el-tag>
            <el-input @blur="toLoock(row)" v-model="row.saleAttrValue" v-if="row.flag==true" placeholder="请你输入属性值" size="small" style="width: 100px;"></el-input>
            <el-button @click="toEdit(row)" v-else type="success" size="small" icon="Plus"></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="130px">
          <template #="{$index}">
            <el-button @click="saleAttr.splice($index,1)" type="error" size="small" icon="Delete"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button :disabled="saleAttr.length>0?false:true" type="primary" @click="save">保存</el-button>
      <el-button style="margin-left: 10px;" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref,computed } from 'vue';
import type { SaleAttrValue,SpuData,AllTradeMark,SpuHasImg,SaleAttrResponseData,HasSaleAttrResponseData,TradeMark,SpuImg,SaleAttr,HasSaleAttr} from '@/api/product/spu/type';
import {reqAllTradeMark,reqSpuImageList,reqSpuHasSaleAttr,reqAllSaleAttr,reqAddOrUpdateSpu} from '@/api/product/spu/index'
import { ElMessage } from 'element-plus'
let $emit = defineEmits(['changeScene'])
// 子组件点击取消按钮：通知父组件切换场景为1，展示SPU列表
const cancel = ()=> {
  $emit('changeScene',{flag:0,params:'update'})
}
// SPU品牌下拉
let allTradeMark = ref<TradeMark[]>([])
// SPU图片
let imgList = ref<SpuImg[]>([])
// 已有的 SPU销售属性列表
let saleAttr = ref<SaleAttr[]>([])
// 全部的 SPU销售属性
let allSaleAttr = ref<HasSaleAttr[]>([])
// 新增SPU对象 6个字段
let spuParams = ref<SpuData>({
  category3Id: '', //三级分类id
  tmId: '', //SPU品牌id
  spuName: '', //SPU名称
  description: '', //SPU描述
  spuImageList:[], //SPU图片列表
  spuSaleAttrList:[], //SPU销售属性列表
})
// 收集还未选择的销售属性的ID与属性值的名字
let saleAttrIdAndValueName = ref<string>('')
// 图片预览对话框显示隐藏
let dialogVisible = ref<boolean>(false)
// 预览图片地址
let dialogImageUrl = ref<string>('')
// 子组件获取数据的方法
const initHasSpuData = async(spuRow:SpuData)=> { // spuRow：父组件传递过来的SPU对象
  spuParams.value = spuRow //修改行数据
  // 获取全部品牌下拉数据
  let result:AllTradeMark = await reqAllTradeMark()
  // 根据id获取SPU下的商品图片数据
  let result1:SpuHasImg = await reqSpuImageList((spuRow.id as number)) //断言为number
  // 根据id获取SPU销售属性列表数据
  let result2:SaleAttrResponseData = await reqSpuHasSaleAttr((spuRow.id as number)) //断言为number
  // 获取整个项目全部的销售属性[颜色、版本、尺码]（SPU销售属性下拉数据）
  let result3:HasSaleAttrResponseData = await reqAllSaleAttr()
  allTradeMark.value = result.data
  imgList.value = result1.data.map(item => {
    return{
      name:item.imgName,
      url:item.imgUrl
    }
  })
  saleAttr.value = result2.data
  allSaleAttr.value = result3.data
}
// 照片墙图片预览
const handlePictureCardPreview = (file:any)=> {
  dialogImageUrl.value = file.url
  dialogVisible.value = true
}
// 图片删除后
const handleRemove = ()=> {
}
// 图片上传成功前
const handleUpload = (file:any)=> {
  if (file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') {
    if(file.size/1024/1024 < 3){
      return true
    }else{
      ElMessage.error('上传文件大小应小于3M！')
      return false
    }
  } else{
    ElMessage.error('上传文件格式：png、jpg、gif！')
    return false
  }
}
// 计算出当前SPU还未拥有的销售属性，作为SPU销售属性下拉数据
// allSaleAttr - saleAttr = unSelectSaleAttr
let unSelectSaleAttr = computed(() => {
  // 全部销售属性：颜色、版本、尺码
  // 已有销售属性：颜色、版本
  let unSelectAttr = allSaleAttr.value.filter(item => { //filter返回条件为真的数据
    return saleAttr.value.every(item1 => {
      return item.name != item1.saleAttrName
    })
  })
  return unSelectAttr
  // every() 检测数组元素是否全部符合指定条件，只要有一个不满足就返回false
  // 第一轮：item.颜色 != item1.颜色 值为false，filter不返回
  // 第二轮：item.版本 != item1.版本 值为false，filter不返回
  // 第三轮：item.尺码 != item1.颜色 且 item.尺码 != item1.版本 值为true，filter返回尺码
})
// 添加销售属性
const addSaleAttr = ()=> {
  // baseSaleAttrId: number, //销售属性id
  // saleAttrName: string, //销售属性名字
  // spuSaleAttrValueList: spuSaleAttrValueList, //销售属性值
  // 数组解构
  const [baseSaleAttrId,saleAttrName] = saleAttrIdAndValueName.value.split(':')
  // 准备一个新的销售属性对象：将来带给服务器即可
  let newSaleAttr:SaleAttr = {
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList:[]
  }
  // 追加到数组当中
  saleAttr.value.push(newSaleAttr)
  // 清空收集的数据
  saleAttrIdAndValueName.value = ''
}
// 属性值按钮点击
const toEdit = (row:SaleAttr)=> {
  // 点击按钮，显示input组件，->编辑模式
  row.flag = true
  row.saleAttrValue = ''
}
// 表单元素失去焦点的回调
const toLoock = (row:SaleAttr)=> {
  const {baseSaleAttrId,saleAttrValue} = row //收集属性id和属性值名字
  let newSaleAttrValue:SaleAttrValue = {
    baseSaleAttrId,
    saleAttrValueName:(saleAttrValue as string)
  }
  // 输入为空判断
  if((saleAttrValue as string).trim()==''){
    ElMessage.error('属性值不能为空！')
    return
  }
  // 判断属性值是否在数组中存在
  let repeat = row.spuSaleAttrValueList.find(item => {
    return item.saleAttrValueName == saleAttrValue
  })
  if(repeat){
    ElMessage.error('属性值不能重复！')
    return
  }
  // 追加新的属性值对象
  row.spuSaleAttrValueList.push(newSaleAttrValue)
  // input blur后切换为查看模式
  row.flag = false
}
const save = async()=> {
  // 照片墙数据
  spuParams.value.spuImageList = imgList.value.map((item:any) => {
    return {
      imgName:item.name,
      imgUrl:(item.response&&item.response.data)||item.url, //如果是新增item.response，则使用item.response.data图片地址
    }
  })
  // SPU销售属性表格数据
  spuParams.value.spuSaleAttrList = saleAttr.value
  let res = await reqAddOrUpdateSpu(spuParams.value)
  if(res.code==200){
    ElMessage.success(spuParams.value.id?'更新成功':'添加成功')
    // 通知父组件切换场景为0
    $emit('changeScene',{flag:0,params:spuParams.value.id?'update':'add'})
  }else{
    ElMessage.error(spuParams.value.id?'更新失败':'添加失败')
  }
}

// 添加一个新的SPU初始化请求方法
const initAddSpu = async(c3Id:number|string)=> {
  // 清空数据
  Object.assign(spuParams.value,{
    category3Id: '', //三级分类id
    tmId: '', //SPU品牌id
    spuName: '', //SPU名称
    description: '', //SPU描述
    spuImageList:[], //SPU图片列表
    spuSaleAttrList:[], //SPU销售属性列表
  })
  // 清空照片墙
  imgList.value = []
  // 清空销售属性
  saleAttr.value = []
  // 清空SPU销售属性下拉
  saleAttrIdAndValueName.value = ''
  // 存储三级分类的id
  spuParams.value.category3Id = c3Id
  // 获取全部品牌下拉数据
  let result1:AllTradeMark = await reqAllTradeMark()
  // 获取整个项目全部的销售属性[颜色、版本、尺码]（SPU销售属性下拉数据）
  let result2:HasSaleAttrResponseData = await reqAllSaleAttr()
  allTradeMark.value = result1.data
  allSaleAttr.value = result2.data
}

// setup语法：对于子组件内部的属性及方法，默认是关闭的，
// 想要父组件使用，需要defineExpose()对外暴露，父组件才能拿到子组件的方法
defineExpose({initHasSpuData,initAddSpu})
</script>

<style scoped lang="scss">

</style>